package com.twu.biblioteca;

import com.twu.biblioteca.menus.*;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

public class BibliotecaApp {

    public static void main(String[] args) throws IOException {
        InputController inputController = new InputController(new BufferedReader(new InputStreamReader(System.in)));
        OutputController outputController = new OutputController(new PrintStream(System.out));

        final List<Book> books = createBooks();
        final List<Movie> movies = createMovies();
        final List<User> users = createUsers();
        final List<String> mainMenuOptions = createMainMenu();
        final UserList userList = new UserList(users);
        final List<Menu> menus = createMenus(inputController, outputController, books, mainMenuOptions, movies, userList);

        final Library library = new Library(menus);

        outputController.drawMessage("Welcome! Please enter the number of the menu option you would like.");
        library.setCurrentMenu(1);
        Menu currentMenu = library.getCurrentMenu();

        while (true) {
            final boolean display = shouldMenuBeDisplayed(currentMenu, userList);
            if (display) {
                currentMenu.displayMenu();
                try {
                    currentMenu.getInput();
                    currentMenu.runCommand();
                    library.setCurrentMenu(currentMenu.getNextMenu());
                    currentMenu= library.getCurrentMenu();
                } catch (IncorrectOptionSelected e) {
                    outputController.printError(e);

                }
            }else{
                outputController.drawMessage("Please log in for this functionality.");
                library.setCurrentMenu(1);
                currentMenu = library.getCurrentMenu();
            }

        }
    }

    private static List<User> createUsers() {
        final List<User> users = new LinkedList<User>();
        users.add(new User(1111111,"Password","John", "john@gmail.com", "7732303511"));
        users.add(new User(1111112,"Password","John", "john@gmail.com", "7732303511"));
        users.add(new User(1111113,"Password","John", "john@gmail.com", "7732303511"));
        return users;
    }

    private static boolean shouldMenuBeDisplayed(Menu currentMenu, UserList userList) {
        return !(currentMenu.mustBeLoggedIn() && !userList.isLoginSet());
    }

    private static List<Movie> createMovies() {
        final LinkedList<Movie> movies = new LinkedList<Movie>();
        for (int i = 0; i < 16; i++) {
            movies.add(new Movie("Movie " + i, "Year " + i, "Director " + i, "Rating " + i));
        }
        return movies;
    }

    private static LinkedList<Menu> createMenus(InputController inputController, OutputController outputController, List<Book> books, List<String> mainMenuOptions, List<Movie> movies, UserList userList) {
        final LinkedList<Menu> menus = new LinkedList<Menu>();
        menus.add(new QuitMenu(outputController));
        menus.add(new MainMenu(mainMenuOptions, outputController, inputController));
        menus.add(new BookMenu(new BookList(books), outputController));
        menus.add(new ReserveBookMenu( outputController, inputController, new BookList(books)));
        menus.add(new MovieMenu(new MovieList(movies),outputController));
        menus.add(new UserMenu( outputController, inputController, userList));
        menus.add(new CheckMembershipDetailsMenu( outputController, userList));
        return menus;
    }

    private static List<String> createMainMenu() {
        final List<String> mainMenuOptions = new LinkedList<String>();
        mainMenuOptions.add("Quit");
        mainMenuOptions.add("Return to main menu");
        mainMenuOptions.add("View Books in collection");
        mainMenuOptions.add("Reserve A Book");
        mainMenuOptions.add("View Movies in collection");
        mainMenuOptions.add("Log in");
        mainMenuOptions.add("Check Membership details");
        return mainMenuOptions;
    }

    private static List<Book> createBooks() {
        final List<Book> books = new LinkedList<Book>();
        books.add(new Book("Moby Dick"));
        books.add(new Book("Blade Runner"));
        books.add(new Book("Scala A Beginners Guide"));
        return books;
    }
}
